﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Elsa.Workflows;
using Elsa.Workflows.State;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Newtonsoft.Json;
using T.FAS.Runtime.MF.Entity;
using T.FAS.Runtime.MF.Entity.ElsaEntity;

namespace T.FAS.Runtime.MF.Activities.ActivityInputOutput
{
    public abstract class AbsActivityExecuteDetailHandler
    {
        public IActivity Activity { get; set; }
        public ActivityExecutionRecord ActivityExecutionRecord { get; set; }
        public IEnumerable<ResolvedVariable> RuntimeVariables { get; set; }
        public WorkflowInstance WorkflowInstance { get; set; }
        public AbsActivityExecuteDetailHandler(
            IActivity activity,
            ActivityExecutionRecord activityExecutionRecord,
            IEnumerable<ResolvedVariable> runtimeVariables,
            WorkflowInstance workflowInstance)
        {
            ActivityExecutionRecord = activityExecutionRecord;
            RuntimeVariables = runtimeVariables;
            WorkflowInstance = workflowInstance;
            Activity = activity;
        }

        public WorkflowInstanceDetail GetActivityExecuteDetail()
        {
            var detail = new WorkflowInstanceDetail();
            detail.ActivityId = Activity.Id;
            detail.RecordId = ActivityExecutionRecord.Id;
            detail.ActitiyName = Activity.Name;
            detail.Status = GetActivityStatus(ActivityExecutionRecord.Status);
            detail.StartTime = ActivityExecutionRecord.StartedAt;
            detail.EndTime = ActivityExecutionRecord.CompletedAt;
            detail.Duration = detail.EndTime.HasValue ? detail.EndTime.Value.Subtract(detail.StartTime.Value).TotalSeconds : default(Nullable<double>);
            detail.NodeType = GetNodeType(ActivityExecutionRecord.ActivityType);

            if (!string.IsNullOrEmpty(ActivityExecutionRecord.SerializedException))
            {
                var exception = JsonConvert.DeserializeObject<ExceptionState>(ActivityExecutionRecord.SerializedException);
                detail.Exception = exception.Message;
            }
            var inputOutput = GetInputOutput();
            detail.Inputs = inputOutput.Inputs;
            detail.Outputs = inputOutput.Outputs;
            return detail;
        }

        private string GetNodeType(string nodeType)
        {
            var convertedNodeType = nodeType;
            switch (nodeType)
            {
                case "T.FAS.Runtime.MF.Activities.ActionExecuteActivity":
                    {
                        convertedNodeType = "action-node"; break;
                    }
                case "T.FAS.Runtime.MF.Activities.CDOActivity":
                    {
                        convertedNodeType = "cdo-node"; break;
                    }
                case "T.FAS.Runtime.MF.Activities.ConditionBranchActivity":
                    {
                        convertedNodeType = "if-else-node"; break;
                    }
                case "T.FAS.Runtime.MF.Activities.DataQueryActivity":
                    {
                        convertedNodeType = "dataquery-node"; break;
                    }
                case "T.FAS.Runtime.MF.Activities.IfActivity":
                    {
                        convertedNodeType = "if-node"; break;
                    }
                case "T.FAS.Runtime.MF.Activities.JavaScriptActivity":
                    {
                        convertedNodeType = "code-node"; break;
                    }
                case "T.FAS.Runtime.MF.Activities.LLMActivity":
                    {
                        convertedNodeType = "llm-node"; break;
                    }
                case "T.FAS.Runtime.MF.Activities.FasIterationActivity":
                case "T.FAS.Runtime.MF.Activities.FasParallelIterationActivity":
                case "Elsa.ForEach":
                case "Elsa.ParallelForEach":
                    {
                        convertedNodeType = "iteration-node"; break;
                    }
                case "T.FAS.Runtime.MF.Activities.FasStartActivity":
                case "Elsa.FasStartActivity":
                    {
                        convertedNodeType = "start-node"; break;
                    }
                case "T.FAS.Runtime.MF.Activities.FasEndActivity":
                case "Elsa.FasEndActivity":
                    {
                        convertedNodeType = "end-node"; break;
                    }
             
                case "T.FAS.Runtime.MF.Activities.IterationStartNode":
                    {
                        convertedNodeType = "group-start-node"; break;
                    }
                
                default: break;
            }
            return convertedNodeType;
        }

        private string GetActivityStatus(string activityStatus)
        {
            var status = activityStatus;
            switch (activityStatus)
            {
                case "Running": { status = "waiting"; break; }
                case "Faulted": { status = "exception"; break; }
                case "Canceled": { status = "stopped"; break; }
                case "Completed": { status = "succeeded"; break; }
                default:
                    break;
            }
            return status;
        }
        public abstract WorkflowInstanceDetail GetInputOutput();

    }
}
